;; The first four lines of this file were added by Dracula.
;; They tell DrScheme that this is a Dracula Modular ACL2 program.
;; Leave these lines unchanged so that DrScheme can properly load this file.
#reader(planet "reader.rkt" ("cce" "dracula.plt") "modular" "lang")
(require "ihipstafy.lisp")
(require "mhuechange.lisp")
(require "mbmptree.lisp")

; The Hipstafy module, responsible for creating Andy Warhol-esque
; reproductions of images. That is, it makes a new image, each of
; whose quadrants is the original image with a different hue.
(module MHipstafy
  (import Ihuechange)
  (import Ibmptree)
  
  ; The helper function to Hipstafy, which actually processes each pixel
  ; and puts them into the new tree.
  ;
  ; pre: width - the original image's width, number
  ;      height - the original image's height, number
  ;      oldtree - the tree of the original image
  ;      newtree - the tree to return as the new image
  ;      xcurr - the x index in the outer for-loop, number
  ;      xmax - the max x value in the outer for-loop, number
  ;      ycurr - the y index in the inner for-loop, number
  ;      ymax - the max y value in the innter for-loop, number
  ;
  ; post: a new bitmap tree, hipstafy'd
  (defun hipstafy-helper (width height oldtree newtree xcurr xmax ycurr ymax)
    ; is the current x index less than its max?
      (if (< xcurr xmax)
          ; yes, is the current y index less than its max?
          (if (< ycurr ymax)
              ; yes, so process the current pixel. make 4 copies of it with different
              ; colors, and add all 4 of these to a new tree with different coordinates
              ; (offset original coords by either the width, height or both)
              (let* ((currpixel (get-pixel-color oldtree xcurr ycurr))
                     ; get the original RGB values
                     (r (car currpixel))
                     (g (cadr currpixel))
                     (b (caddr currpixel))
                     ; make 4 copies of the original pixel, but alter the hue on each
                     (newpixel1 (pixel-to-hue-original r g b 89))
                     (newpixel2 (pixel-to-hue-original r g b 179))
                     (newpixel3 (pixel-to-hue-original r g b 269))
                     (newpixel4 (pixel-to-hue-original r g b 359))
                     ; insert each one into the new tree, but change the quadrant
                     (tr1 (insert-pixel newtree (list xcurr ycurr newpixel1)))
                     (tr2 (insert-pixel tr1 (list (+ xcurr height) ycurr newpixel2)))
                     (tr3 (insert-pixel tr2 (list xcurr (+ ycurr width) newpixel3)))
                     (tr4 (insert-pixel tr3 (list (+ xcurr height) (+ ycurr width) newpixel4))))
                ; recursively call itself and process the next pixel
                (hipstafy-helper width height oldtree tr4 xcurr xmax (+ ycurr 1) ymax))
              ; no, so reset y to 0 and increment x
              (hipstafy-helper width height oldtree newtree (+ xcurr 1) xmax 0 ymax))
          ; x has extended past its max, so the recursion is done - return the new tree
          newtree))
  
  ; The Hipstafy function, which takes a tree and calls its helper
  ; function to produce the new image.
  ;
  ; pre: tree - a bitmap tree
  ; post: a new bitmap tree with the processed image
  (defun hipstafy (tree)
    (if (bmp-tree? tree)
        (let* ((oldheader (get-header tree))
               (oldheight (car (get-dimensions tree)))
               (oldwidth (cdr (get-dimensions tree)))
               (newwidth (* 2 oldwidth))
               (newheight (* 2 oldheight))
               (tmptree (insert-header (empty-bmp-tree) oldheader))
               (newtree (set-dimensions-header tmptree newheight newwidth)))
          (hipstafy-helper oldwidth oldheight tree newtree 0 oldheight 0 oldwidth))
        tree))
  
  (export Ihipstafy))